using System.Collections;
using System.Collections.Generic;
using FrameWork;
using FrameWork.Inventory;
using FrameWork.TileMapManager;
using UnityEngine;

public class SaveData : MonoBehaviour
{
    [SerializeField] private PlayerDataSO playerDataSO;
    [SerializeField] private MapModel mapModel;
    [SerializeField] private InventorySO inventorySO;
    [SerializeField] private TimeDataSO timeDataSO;

    /// <summary>
    /// 保存玩家数据的结构体
    /// </summary>
    /// <returns></returns>
    public SaveDataInfo GetSaveDataInfo()
    {
        return new SaveDataInfo(playerDataSO.PlayerLv, playerDataSO.PlayerCoins, playerDataSO.PlayerCurrentExp,
            timeDataSO.CurrentDay, timeDataSO.CurrentYear, timeDataSO.CurrentSeason, timeDataSO.CurrentHour, timeDataSO.CurrentDayOfWeek);
    }
    
    public SaveDataInfo CreatSaveDataInfo()
    {
        return new SaveDataInfo(1, 100, 0, 1, 1, 1, 1, 1);
    }
    
    // public SaveDataInfo GetSaveDataInfo()
    // {
    //     return new SaveDataInfo(
    //         playerDataSO.PlayerLv,
    //         playerDataSO.PlayerCoins,
    //         playerDataSO.PlayerCurrentExp,
    //         new SerializableList<InventoryItem>(inventorySO.GetMyInventorys),
    //         new SerializableDictionary<string, int>(inventorySO.GetItemDic),
    //         timeDataSO.CurrentDay,
    //         timeDataSO.CurrentYear,
    //         timeDataSO.CurrentSeason,
    //         timeDataSO.CurrentHour,
    //         timeDataSO.CurrentDayOfWeek,
    //         new SerializableList<Vector3Int>(mapModel.CultivatedTiles),
    //         new SerializableDictionary<Vector3Int, CropData>(mapModel.CropDatasDicTiles)
    //     );
    // }
    //
    // public SaveDataInfo CreatSaveDataInfo()
    // {
    //     return new SaveDataInfo(
    //         1, 
    //         100, 
    //         0,
    //         new SerializableList<InventoryItem>(new List<InventoryItem>()),
    //         new SerializableDictionary<string, int>(new Dictionary<string, int>()),
    //         1, 
    //         1, 
    //         1, 
    //         1, 
    //         1,
    //         new SerializableList<Vector3Int>(new List<Vector3Int>()),
    //         new SerializableDictionary<Vector3Int, CropData>(new Dictionary<Vector3Int, CropData>())
    //     );
    // }
}


// 可序列化类，用于存储数据
[System.Serializable]
public class SaveDataInfo
{
    // 玩家数据
    [field: SerializeField] private int playerLv;
    public int PlayerLv
    {
        get { return playerLv; }
        set { playerLv = value; }
    }
    [field: SerializeField] private int playerCoins;
    public int PlayerCoins
    {
        get { return playerCoins; }
        set { playerCoins = value; }
    }
    [field: SerializeField] private int playerCurrentExp;
    public int PlayerCurrentExp
    {
        get { return playerCurrentExp; }
        set { playerCurrentExp = value; }
    }
    
    
    // 时间数据
    [field: SerializeField] private int currentDay;
    public int CurrentDay
    {
        get { return currentDay; }
        set { currentDay = value; }
    }
    [field: SerializeField] private int currentYear;
    public int CurrentYear
    {
        get { return currentYear; }
        set { currentYear = value; }
    }
    [field: SerializeField] private int currentSeason;
    public int CurrentSeason
    {
        get { return currentSeason; }
        set { currentSeason = value; }
    }
    [field: SerializeField] private int currentHour;
    public int CurrentHour
    {
        get { return currentHour; }
        set { currentHour = value; }
    }
    [field: SerializeField] private int currentDayOfWeek;
    public int CurrentDayOfWeek
    {
        get { return currentDayOfWeek; }
        set { currentDayOfWeek = value; }
    }

    // 库存数据
    private SerializableList<InventoryItem> myInventorysSerializable;
    public List<InventoryItem> MyInventorys
    {
        get { return myInventorysSerializable.Target; }
        set { myInventorysSerializable = new SerializableList<InventoryItem>(value); }
    }
    private SerializableDictionary<string, int> itemDicSerializable;
    public Dictionary<string, int> ItemDic
    {
        get { return itemDicSerializable.Target; }
        set { itemDicSerializable = new SerializableDictionary<string, int>(value); }
    }
    
    // 瓦片地图
    private SerializableList<Vector3Int> cultivatedTilesSerializable;
    public List<Vector3Int> CultivatedTiles
    {
        get { return cultivatedTilesSerializable.Target; }
        set { cultivatedTilesSerializable = new SerializableList<Vector3Int>(value); }
    }
    private SerializableDictionary<Vector3Int, CropData> cropDatasDicSerializable;
    public Dictionary<Vector3Int, CropData> CropDatasDic
    {
        get { return cropDatasDicSerializable.Target; }
        set { cropDatasDicSerializable = new SerializableDictionary<Vector3Int, CropData>(value); }
    }

    // 构造函数
    // public SaveDataInfo(int playerLv, int playerCoins, int playerCurrentExp,
    //     List<InventoryItem> myInventorys, Dictionary<string, int> itemDic,
    //     int currentDay, int currentYear, int currentSeason, int currentHour, int currentDayOfWeek,
    //     List<Vector3Int> cultivatedTiles, Dictionary<Vector3Int, CropData> cropDatasDic)
    // {
    //     this.playerLv = playerLv;
    //     this.playerCoins = playerCoins;
    //     this.playerCurrentExp = playerCurrentExp;
    //     this.MyInventorys = myInventorys;
    //     this.ItemDic = itemDic;
    //     this.currentDay = currentDay;
    //     this.currentYear = currentYear;
    //     this.currentSeason = currentSeason;
    //     this.currentHour = currentHour;
    //     this.currentDayOfWeek = currentDayOfWeek;
    //     this.CultivatedTiles = cultivatedTiles;
    //     this.CropDatasDic = cropDatasDic;
    // }
    
    public SaveDataInfo(int playerLv, int playerCoins, int playerCurrentExp,
        int currentDay, int currentYear, int currentSeason, int currentHour, int currentDayOfWeek
       )
    {
        this.playerLv = playerLv;
        this.playerCoins = playerCoins;
        this.playerCurrentExp = playerCurrentExp;
        this.currentDay = currentDay;
        this.currentYear = currentYear;
        this.currentSeason = currentSeason;
        this.currentHour = currentHour;
        this.currentDayOfWeek = currentDayOfWeek;
    }
}

[System.Serializable]
public class SerializableList<T>
{
    [SerializeField]
    private List<T> target;

    public List<T> Target
    {
        get { return target; }
        set { target = value; }
    }

    public SerializableList(List<T> list)
    {
        target = list;
    }

    public static implicit operator List<T>(SerializableList<T> serializableList)
    {
        return serializableList.target;
    }

    public static implicit operator SerializableList<T>(List<T> list)
    {
        return new SerializableList<T>(list);
    }
}

[System.Serializable]
public class SerializableDictionary<TKey, TValue> where TKey : notnull
{
    [SerializeField]
    private List<TKey> keys = new List<TKey>();
    [SerializeField]
    private List<TValue> values = new List<TValue>();

    private Dictionary<TKey, TValue> target;

    public Dictionary<TKey, TValue> Target
    {
        get
        {
            if (target == null)
            {
                target = new Dictionary<TKey, TValue>();
                for (int i = 0; i < keys.Count; i++)
                {
                    target.Add(keys[i], values[i]);
                }
            }
            return target;
        }
        set
        {
            target = value;
            keys = new List<TKey>(value.Keys);
            values = new List<TValue>(value.Values);
        }
    }

    public SerializableDictionary(Dictionary<TKey, TValue> dictionary)
    {
        Target = dictionary;
    }

    public static implicit operator Dictionary<TKey, TValue>(SerializableDictionary<TKey, TValue> serializableDict)
    {
        return serializableDict.Target;
    }

    public static implicit operator SerializableDictionary<TKey, TValue>(Dictionary<TKey, TValue> dictionary)
    {
        return new SerializableDictionary<TKey, TValue>(dictionary);
    }
}